<?php

class PurchaseOrderController extends BaseController {
	
	// Table
	public $table = 'purchase_order';
	
	// Eloquent Model
	public $model = 'PurchaseOrder';
	
	// Base
	public $base = 'po';
	
	// Localization
	public $local = 'en';
	
	// Language Name
	public $language = 'po';
	
	// Breadcrumbs
	public $breadcrumbs = [ ['link' => 'po' , 'title' => 'Purchase Order'] ];

	// Set List Data - Input, Object
	public function setListData( $data, $object ) {
		$object = $this->_filterPoList( $data, $object );
		return $object;
	}

	/**
	 * Filter PO List from Form Filters.
	 * @author AngelaMisa 03/03/2015 11:44PM
	 * @param $data, $object
	 * @return $mixed
	 */
	private function _filterPoList( $data, $object ) {
		if ( !empty($data['filter_id']) )
			$object = $object->where( 'id', (int) $data['filter_id'] );
		
		if ( !empty($data['filter_po_number']) ) {
			$po_num_list = explode('-', trim($data['filter_po_number']));
		
			if ( count($po_num_list) == 3 ) {
				$id = ltrim(trim($po_num_list[1]), 1);
				$vendor = trim($po_num_list[0]);
				$po_date = date_create_from_format( 'Ymd', trim($po_num_list[2]) );
		
				$object = $object->where( 'id', $id )
				->whereHas('vendor', function( $q ) use ( $vendor) {
					$q->where( 'code', $vendor );
				})
				->where( DB::RAW("DATE_FORMAT(created_at, '%Y-%m-%d')"), $po_date->format('Y-m-d') );
			}
			// PO Number doesn't exist
			else
				$object = $object->where( 'id', 0 );
		}
		if ( !empty($data['filter_vendor']) )
			$object = $object->where('VENDOR_id', $data['filter_vendor'] );
		
		if ( isset($data['filter_status']) && $data['filter_status'] != 'all' )
			$object = $object->where('status', (int) $data['filter_status'] );
		
		if ( !empty($data['filter_po_shipping']) )
			$object = $object->where('shipping_method', trim(strtoupper($data['filter_po_shipping'])) );
		
		return $object;
	}
	
	// Add List Data - Additional Data on List
	public function addListData( $data ) {
		$data['vendors'] = array('All Suppliers');
		
		$vendors = Vendor::has('purchaseOrders')->get(array('name', 'id'));
		
		foreach( $vendors as $vendor )
			$data['vendors'][$vendor->id] = ucwords($vendor->name);
	
		$data['statuses'] = array_merge( array('all' => 'All Statuses'), Constant::getPoList( true ) );
		$data['shippings'] = array_merge( array(0 => 'All Shipping Addresses'), Constant::getShippingList( true ) );

		return $data;
	}

	// Add Form Data - Additional Data on Form
	public function addFormData( $data, $id=null ) {
		if ( empty($id) ) return $data;
		
		$data['statuses'] = Constant::getPoList( true );
		$data['order_statuses'] = Constant::getOrderList( true );
		
		return $data;
	}
	
	public function preUpdate( $data ) {
		if ( isset($data['comment']) )
			$data['comment'] = trim($data['comment']);

		if ( ($data['status'] == Constant::PO_DENIED) && empty($data['comment']) )
			$this->rules['comment'] = 'required';
		
		return $data;
	}
	
	public function postUpdate( $data, $object ) {
		$object->status = $data['status'];
		$object->comment = $data['comment'];

		// Has been approved? Update Order Products under it
		if ( $object->status == Constant::PO_APPROVED ) {
			$object->approved_by = Auth::user()->id;
			$object->approved_at = DB::raw('CURRENT_TIMESTAMP');
			$affected_rows = OrderProduct::whereIn( 'id', $object->purchaseOrderProducts->lists('ORDER_PRODUCT_id') )
				->update( ['status' => Constant::ORDER_ORDERED_FROM_SUPPLIER] );
		}
		
		$object->save();
		
		return $data;
	}
	
	// Use to add show on Data
	public function addShowData($data, $id=null) {
		return $data;
	}
	
	/**
	 * Date & Time: 03/02/2015 - 05:26 PM
	 * @param string $id
	 * @return string
	 * Description: Added Purchase Orders View via AJAX 
	 */
	public function getPurchaseOrderdetails($id = null){
		$this->setFormData($id);
		return View::make('po-show')->with($this->data);
	}
	
	/**
	 * Approve selected POs
	 * Date & Time: 03/03/2015
	 * @author Geoff
	 * @return array
	 */
	public function approvePurchaseOrders(){
	
		$ids = explode(',', Input::get('ids') );
		$purchase_order_product = PurchaseOrderProduct::whereIn('id',$ids);
		
		$purchase_order_product->update(array('receive_include'=>1));
		
		$order_product_id = $purchase_order_product->lists('ORDER_PRODUCT_id');
		OrderProduct::whereIn('id',$order_product_id)->update(array('status' => Constant::ORDER_RECEIVED));
		
	
		return [ 'success' => Lang::get('po.po_received_message') ];
	}

/**
	 * Export file for Purchase Order ID.
	 * @author AngelaMisa 02/27/2015
	 * @param $id, $print
	 * @return void
	 */
	public function export( $id, $template = 'default', $print = false ) {
		$po = PurchaseOrder::where('id', $id)->first();
	
		if ( empty($po) ) return App::abort(404, "Purchase Order {$id} Not Found");

		// Vendor Details
		$vendor = $po->vendor;

		// Build PO Additional Details
		$po_id = array($vendor->code, str_pad($po->id, 3, '0', STR_PAD_LEFT), date_format($po->created_at, 'Ymd'));
		$po_details = array(
			'po_number'			=> implode('_', $po_id),
			'po_date'			=> 'N/A',
			'delivery_date'		=> 'N/A',
			'prepared_by'		=> $po->createdBy->firstname . ' ' . $po->createdBy->lastname,
			'prepared_at'		=> Formatter::toDateFormat( $po->created_at, 'm/d/Y' ),
			'approved_by'		=> 'N/A',
			'approved_at'		=> 'N/A',
			'delivery_date'		=> 'N/A',
			'shipping_address'	=> array(
				'address'	=> Lang::get('info.ACOMMERCE.address'),
				'unit'		=> Lang::get('info.ACOMMERCE.building'),
				'street'	=> Lang::get('info.ACOMMERCE.street'),
				'city'		=> Lang::get('info.ACOMMERCE.city'),
				'postal'	=> Lang::get('info.ACOMMERCE.postal'),
				'mobile'	=> 'N/A',
			),
			'comments'			=> $po->comment,
			'total_price'		=> 0,
			'total_quantity'	=> 0
		);
		
		// Is PO Approved already?
		if ( $po->status == Constant::PO_APPROVED ) {
			$str_approved_at = Formatter::toDateFormat( $po->approved_at, 'm/d/Y' );
			$po_details['po_date']			= $str_approved_at;
			$po_details['approved_at']		= $str_approved_at;
			$po_details['approved_by']		= $po->approvedBy->firstname . ' ' . $po->approvedBy->lastname;
			$po_details['delivery_date']	= Formatter::toDateFormat( $po->approved_at, 'm-d-Y', 7 );
		}
	
		// Retrieve Distinct Products Quantity and Option Value
		$products = array();
		foreach ( $po->purchaseOrderProducts as $item ) {
			$op = $item->orderProduct;
			$product_id = (int) $op->PRODUCT_id;
			$quantity = (int) $op->quantity;
			$order_id = (int) $op->ORDER_id;
	
			// Product ID not yet saved? Initialized
			if ( !array_key_exists($product_id, $products) ) {
				$products[$product_id] = array(
					'model'		=> $op->product->code,
					'name'		=> $op->product->name,
					'sku'		=> str_replace($vendor->code . '-', '', $op->product->code),
					'quantity'	=> 0,
					'price'		=> $op->product->srp,
					'total'		=> 0,
					'options'	=> array()
				);
			}
			
			// Get Product Options. Note: unarchived.
			$prod_options = OrderProductOption::where('ORDER_id', '=', $order_id)
				->where('PRODUCT_id', '=', $product_id)
				->get();
			
			$prod_add_price = 0;
			if ( !empty($prod_options) ) {
				foreach ( $prod_options as $option ) {
					$opt_val_id = trim($option->option_value);
					
					// New Product Option?
					if ( !array_key_exists($opt_val_id, $products[$product_id]['options']) ) {
						$products[$product_id]['options'][$opt_val_id] = array(
							'quantity' => 0, 'value' => $opt_val_id, 'price' => $option->price, 'total' => 0
						);
					}
					
					// Use Order Item Product quantity if option is only one.
					if ( ($prod_options->count() === 1) )
						$opt_qty = $quantity;
					else
						$opt_qty = ( (int) $option->quantity === 0 ) ? 1 : $option->quantity;			
					
					// Compute for Option Total Quantity and Additional Price
					$opt_total 		= $opt_qty * $option->price;
					$prod_add_price += $opt_total;
					$products[$product_id]['options'][$opt_val_id]['quantity']	+= $opt_qty;
					$products[$product_id]['options'][$opt_val_id]['total']		+= (float) $opt_total;
				}
			}
		
			
			// Compute for Products Total Quantity and Total Price with Additionals
			$item_total 							=  $prod_add_price + ($quantity * $op->product->srp);
			$products[$product_id]['total']			+= $item_total;
			$products[$product_id]['quantity']		+= $quantity;
			$po_details['total_price']				+= $item_total;
			$po_details['total_quantity'] 			+= $quantity;

			// Is for HOME Delivery? Get Order Product Shipping Address
			if ( $po->shipping_method == Constant::PO_SHIPPING_HOME ) {
				$order_set = OrderToSet::where(array(
					'ORDER_id'	=> $op->ORDER_id,
					'SET_id'	=> $op->SIZE_id
				))->first();
				
				// Address Found
				if ( $order_set ) {
					$po_details['shipping_address']	= array(
						'address'	=> $order_set->address,
						'unit'		=> $order_set->unit,
						'street'	=> $order_set->street . ' ' . $order_set->barangay,
						'city'		=> $order_set->city,
						'postal'	=> $order_set->zip_code,
						'mobile'	=> $order_set->mobile,
					);
				}
			}
		}
		$po = array( 'po_info' => $po_details, 'vendor'	=> $vendor, 'products' => $products, 'is_print'	=> !empty($print) );
		
		return View::make('export.po_' . $template . '_excel')->with(array_merge($po, Lang::get('css')));
	}

	/**
	 * Export List of Purchase Orders based on filters.
	 * @author AngelaMisa 03/03/2015 11:49PM
	 * @param $print
	 * @return void
	 */
	public function exportList( $print = false ) {
		$data			= Input::all();
		$po_items		= array();
		$po_options		= array();
		$po_filtered	= $this->_filterPoList( $data, PurchaseOrder::active() );
		$po_ids			=  $po_filtered->lists('id');
		
		// Has PO filtered?
		if ( $po_filtered->count() ) {
			$po_result = PurchaseOrderProduct::active()
				->whereIn('PURCHASE_ORDER_id', $po_ids );
			
			// Retrieve Purchase Order Items based on Filtered PO List
			$po_items = $po_result->join('purchase_order', 'purchase_order_product.PURCHASE_ORDER_id', '=', 'purchase_order.id')
				->join('vendor', 'purchase_order.VENDOR_id', '=', 'vendor.id')
				->join( 'order_product', 'order_product.id', '=', 'purchase_order_product.ORDER_PRODUCT_id' )
				->join( 'product', 'order_product.PRODUCT_id', '=', 'product.id' )
				->join( 'user', 'user.id', '=', 'purchase_order.created_by')
				->get( array(
					'purchase_order.id AS po_id', 'purchase_order.approved_at', 'purchase_order.created_at',
					'purchase_order.company_code', 'purchase_order.status AS po_status', 'purchase_order.comment AS po_comment',
					'vendor.id AS vendor_id', 'vendor.name AS vendor_name', 'vendor.code AS vendor_code',
					'order_product.id AS item_id', 'order_product.ORDER_id', 'order_product.quantity AS quantity',
					'order_product.name AS prod_name', 'order_product.model AS prod_model', 'product.srp AS prod_srp',
					'order_product.status AS item_status', 'order_product.PRODUCT_id', 'user.lastname', 'user.firstname'
			));
				
			// Retrieve Order Options based on Filtered PO List. Note: No Archived options yet.
			$order_options = OrderProductOption::join( 'order_product', function( $join ) {
					$join->on('order_product_option.ORDER_id', '=', 'order_product.ORDER_id');
					$join->on('order_product_option.PRODUCT_id', '=', 'order_product.PRODUCT_id');
				})
				->join( 'purchase_order_product', 'purchase_order_product.ORDER_PRODUCT_id', '=', 'order_product.id')
				->whereIn('PURCHASE_ORDER_id', $po_ids )
				->get(array('order_product_option.ORDER_id', 'order_product_option.PRODUCT_id AS PRODUCT_id', 'order_product_option.price',
					'order_product_option.option_value', 'order_product_option.quantity', 'order_product.quantity AS order_quantity'
				));
			
			// Prepare Order Options
			foreach ( $order_options as $order_opt ) {
				$opt_id = $order_opt->ORDER_id . '_' . $order_opt->PRODUCT_id;
				$po_options[$opt_id][] = array(
					'option_value'	=> $order_opt->option_value,
					'price'			=> number_format($order_opt->price, 2),
					'quantity'		=> ( (int) $order_opt->quantity === 0 ) ? $order_opt->order_quantity : $order_opt->quantity
				);
			}
		}
		
		$po_list['po_list'] = array(
			'cur_date'			=> Formatter::toDateFormat('now', 'Y-m-d h:i:s'),
			'is_print'			=> $print,
			'items'				=> $po_items,
			'options'			=> $po_options,
			'statuses'			=> Constant::getPoList( true ),
			'order_statuses'	=> Constant::getOrderList( true )
		);

		return View::make( 'export.po_list' )->with( array_merge($po_list, Lang::get('css')) );
	}
	
	/**
	 * Generate Sales Order Report.
	 * Item-level.
	 * @param $print
	 * @return void
	 */
	public function generateSO( $print = false ) {
		$get_data = PurchaseOrderProduct::select( array(
			'order.id','order.payment_method', 'order.created_at', 'order_product.quantity', 'order_product.benstore_price',
			'login.email', 'login.firstname', 'login.lastname', 'order_product.peso', 'order_product.SIZE_id',
			'order_to_set.unit', 'order_to_set.street', 'order_to_set.barangay', 
			'order_to_set.city', 'order_to_set.zip_code', 'order_to_set.mobile',
			'product.code' ) )
		->join( 'purchase_order', 'purchase_order_product.PURCHASE_ORDER_id','=','purchase_order.id' )
		->join( 'order_product','order_product.id','=','purchase_order_product.ORDER_PRODUCT_id' )
		->join( 'order' , 'order_product.ORDER_id', '=', 'order.id' )
		->leftJoin( 'order_to_set', function ( $order_set ) {
			$order_set->on('order_to_set.ORDER_id', '=', 'order_product.ORDER_id')
				->on('order_to_set.SET_id', '=', 'order_product.SIZE_id');
		})
		->join( 'login', 'order.EMPLOYEE_id', ' = ', 'login.id')
		->join( 'product', 'order_product.PRODUCT_id', ' = ', 'product.id')
		->where( 'purchase_order.status', Constant::PO_APPROVED )
		->where( 'order.so_batch','=', null )
		->where( 'order_product.status', '=' , Constant::ORDER_ORDERED_FROM_SUPPLIER )//3
		//->where( 'order.status', '=' , Constant::ORDER_ORDERED_FROM_SUPPLIER )
		->whereRaw( '(SELECT COUNT(*) FROM order_product op WHERE op.ORDER_id = order_product.ORDER_id and SIZE_id <> 7)
			=(SELECT COUNT(*) FROM order_product op WHERE op.ORDER_id = order_product.ORDER_id AND op.status=2)' );
		$get_so['so_list'] = $get_data->get();
		$get_so['so_statuses'] = Constant::getOrderList( true );
		$get_so['is_print'] = (bool) $print;
		
		return View::make( 'export.salesorder' )->with( $get_so );
	}
	
	/**
	 * View of Upload approved PO statuses
	 * @author Geoffrey
	 * @return view
	 */
	public function uploadPurchaseOrderStatus(){
		return View::make('po-upload_purchase_order_status');
	}
	
	/**
	 * Post upload file of PO Status
	 * @author Geoffrey
	 * @return array
	 */
	public function postUploadPurchaseOrderStatus(){
		$dir	= Config::get('app.lbea');
		$file 	= Input::file('postUploadPurchaseOrderStatus');
		$moved				= $file->move($dir,$file->getClientOriginalName());
		$uploaded_file		= array();
		$uploaded_data	= array();
		if($moved){
			$uploaded_file = fopen($dir . '/' . Input::file('postUploadPurchaseOrderStatus')->getClientOriginalName(), 'r');
		}
		if($uploaded_file){
			$c=0;
			$row = 0;
			//debug(@feof($uploaded_file));
			while (($data = fgetcsv($uploaded_file, 1000, ",")) !== FALSE) {
				$num = count($data);
				$row++;
				for ($c=0; $c < $num; $c++) {
					$uploaded_data[$row][] = $data[$c];
				}
			}
		}
		unset($uploaded_data[1]);
		foreach($uploaded_data AS $count_upload => $upload_data){
			if(PurchaseOrderProduct::where('ORDER_PRODUCT_id', '=', $upload_data[0])->first()->receive_include == 1){
				$order_product = OrderProduct::find($upload_data[0]);
				$order_product->status = Constant::ORDER_RECEIVED;
				$order_product->save();
			}
		}
		return [ 'success' => 1 ];
	}
	
	}
	